﻿using DevExpress.XtraEditors;
using EyFramework.Common;
using System;
using System.Drawing;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraSplashScreen;
using EyFramework.Library.Control;

namespace EyFramework.Library
{
    public partial class FrmDevBase : XtraForm, IFormBase
    {
        public DevExpress.LookAndFeel.DefaultLookAndFeel DefaultLookAndFeel;

        public OverlayWindowOptions Options;
        public bool IsShowOverlayForm = false;
        private IOverlaySplashScreenHandle overlayHandle;
        private OverlayTextPainter overlayLabel;

        public FrmDevBase()
        {
            InitializeComponent();
            this.DefaultLookAndFeel = new DevExpress.LookAndFeel.DefaultLookAndFeel();
            overlayLabel = new OverlayTextPainterEx()
            {
                Text = "数据处理中,请稍后...",
                Font = new Font("微软雅黑", 10, FontStyle.Regular),
                Color = Color.DodgerBlue
            };

            this.Options = new OverlayWindowOptions()
            {
                AnimationType = WaitAnimationType.Image,
                SkinName = "Office 2019 Colorful",
                ImageSize = new Size(64, 64),
                BackColor = Color.FromArgb(165, 165, 165),
                ForeColor = Color.White,
                FadeIn = true,
                FadeOut = true,
                Opacity = 80
            };
            LoadSkin();
        }

        public void LoadSkin()
        {
            if (Globals.appConfigure != null)
                SetSkin(Globals.GetSysConfig(EyFramework.Common.Constants.CFG_SkinName));
        }

        public void SetSkin(string skinName)
        {
            this.DefaultLookAndFeel.LookAndFeel.SkinName = skinName;
        }

        /// <summary>
        /// 异步线程方法，异步使用多线程的方式调用函数，
        /// 注意，此方法的使用条件，异步调用的函数内部不能做操作主线程的事情，比如更新界面UI。如果确实需要，请使用invoke 委托的方式更新，
        /// 而不能直接更新
        /// </summary>
        /// <param name="action"></param>
        /// <param name="showLoading"></param>
        /// <returns></returns>
        public object DoTaskAsync(Func<object> action, bool showLoading = false)
        {
            if (showLoading)
            {
                ShowLoading("异步处理中，请耐心等待...");
            }
            try
            {
                Task<object> task = new Task<object>(action);
                task.Start();
                task.Wait();
                if (showLoading)
                {
                    CloseLoading();
                }
                Application.DoEvents();
                return task.Result;
            }
            catch (Exception ex)
            {
                CloseLoading();
                if (ex.InnerException != null)
                {
                    throw ex.InnerException;
                }
                else
                {
                    throw ex;
                }
            }
        }

        /// <summary>
        /// 异步任务，不关心结果，调用后，继续主线程的操作。
        /// </summary>
        /// <param name="action"></param>
        /// <param name="showLoading"></param>
        public void DoActionAsync(Action action)
        {
            Task task = new Task(action);
            task.Start();
        }

        public void ShowLoading(string loadingText = "")
        {
            if (!loading.IsSplashFormVisible)
            {
                loading.ShowWaitForm();
                if (!string.IsNullOrEmpty(loadingText))
                {
                    loading.SetWaitFormDescription(loadingText);
                }
            }
        }

        public void CloseLoading()
        {
            if (loading.IsSplashFormVisible)
            {
                loading.CloseWaitForm();
            }
        }

        public void ShowWaiting(string showText = "")
        {
            if (!string.IsNullOrEmpty(showText))
            {
                overlayLabel.Text = showText;
            }
            else
            {
                overlayLabel.Text = "数据处理中，请稍后";
            }
            if (!IsShowOverlayForm)
            {
                overlayHandle = SplashScreenManager.ShowOverlayForm(this.ParentForm == null ? this : this.ParentForm, fadeIn: Options.FadeIn,
                    fadeOut: Options.FadeOut, backColor: Options.BackColor, foreColor: Options.ForeColor,
                    opacity: 80, imageSize: Options.ImageSize,
                    animationType: Options.AnimationType, skinName: Options.SkinName,
                    customPainter: new OverlayWindowCompositePainter(overlayLabel));
                IsShowOverlayForm = !IsShowOverlayForm;
            }
        }

        public void CloseWaiting()
        {
            if (IsShowOverlayForm)
            {
                overlayHandle.Close();
                IsShowOverlayForm = !IsShowOverlayForm;
            }
        }
    }
}